package com.the_last.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

@Slf4j
@Component
@RequiredArgsConstructor
public class OSSUtil {
    
    private final OSS ossClient;
    
    @Value("${aliyun.oss.bucketName}")
    private String bucketName;
    
    /**
     * 上传文件
     *
     * @param file 文件
     * @param dir  目录
     * @return 文件访问路径
     */
    public String uploadFile(MultipartFile file, String dir) {
        String originalFilename = file.getOriginalFilename();
        String extension = null;
        if (originalFilename != null) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + extension;
        String objectName = dir + "/" + fileName;
        
        try {
            InputStream inputStream = file.getInputStream();
            // 创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            if (extension != null) {
                metadata.setContentType(getContentType(extension));
            }
            metadata.setContentLength(file.getSize());
            
            // 上传文件
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream, metadata);
            ossClient.putObject(putObjectRequest);
            
            // 返回文件访问路径
            return objectName;
        } catch (IOException e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败");
        }
    }
    
    /**
     * 获取文件类型
     *
     * @param extension 文件扩展名
     * @return 文件类型
     */
    private String getContentType(String extension) {
        // 文件类型映射
        if (extension.equalsIgnoreCase(".bmp")) return "image/bmp";
        if (extension.equalsIgnoreCase(".gif")) return "image/gif";
        if (extension.equalsIgnoreCase(".jpeg") || extension.equalsIgnoreCase(".jpg")) return "image/jpeg";
        if (extension.equalsIgnoreCase(".png")) return "image/png";
        if (extension.equalsIgnoreCase(".html")) return "text/html";
        if (extension.equalsIgnoreCase(".txt")) return "text/plain";
        if (extension.equalsIgnoreCase(".vsd")) return "application/vnd.visio";
        if (extension.equalsIgnoreCase(".ppt") || extension.equalsIgnoreCase(".pptx"))
            return "application/vnd.ms-powerpoint";
        if (extension.equalsIgnoreCase(".doc") || extension.equalsIgnoreCase(".docx"))
            return "application/msword";
        if (extension.equalsIgnoreCase(".xml")) return "text/xml";
        return "application/octet-stream";
    }
    
    /**
     * 上传输入流
     *
     * @param inputStream   输入流
     * @param fileName      文件名
     * @param dir           目录
     * @param contentLength 文件大小
     * @return 文件访问路径
     */
    public String uploadStream(InputStream inputStream, String fileName, String dir, long contentLength) {
        String extension = fileName.substring(fileName.lastIndexOf("."));
        String objectName = dir + "/" + UUID.randomUUID().toString().replaceAll("-", "") + extension;
        
        try {
            // 创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(getContentType(extension));
            metadata.setContentLength(contentLength);
            
            // 上传文件
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream, metadata);
            ossClient.putObject(putObjectRequest);
            
            return objectName;
        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败");
        }
    }
}